package com.familyigo.gdemo;

import org.jdbi.v3.core.statement.SqlLogger;
import org.jdbi.v3.core.statement.StatementContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.Duration;

public class MySqlLogger implements SqlLogger {
    private final Logger log;

    public MySqlLogger() {
        this(LoggerFactory.getLogger("org.jdbi.sql"));
    }

    public MySqlLogger(Logger log) {
        this.log = log;
    }

    @Override
    public void logAfterExecution(StatementContext context) {
        if (log.isDebugEnabled()) {
            log.debug("Executed in {} '{}' with parameters '{}'",
                    format(Duration.between(context.getExecutionMoment(), context.getCompletionMoment())),
                    getSql(context),
                    context.getBinding());
        }
    }

    @Override
    public void logException(StatementContext context, SQLException ex) {
        if (log.isErrorEnabled()) {
            log.error("Exception while executing '{}' with parameters '{}'",
                    getSql(context),
                    context.getBinding(),
                    ex);
        }
    }

    private static String getSql(StatementContext context) {
        PreparedStatement statement = context.getStatement();
        if (statement != null) {
            return statement.toString();
        }
        return "<not available>";
    }

    private static String format(Duration duration) {
        final long totalSeconds = duration.getSeconds();
        final long h = totalSeconds / 3600;
        final long m = (totalSeconds % 3600) / 60;
        final long s = totalSeconds % 60;
        final long ms = duration.toMillis() % 1000;
        return String.format(
                "%d:%02d:%02d.%03d",
                h, m, s, ms);
    }
}
